package br.com.games.daedal.ui;

import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Stroke;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;

import br.com.games.daedal.Box;
import br.com.games.daedal.DaedalTeam;
import br.com.games.daedal.Vertex;
import br.com.games.daedal.imp.Daedal;
import br.com.games.daedal.imp.DaedalBoard;
import br.com.games.hefesto.Move;
import br.com.games.hefesto.board.Board;

public class SwingBoard extends JPanelBoard {

	/**
	 * 
	 * @param vertex
	 */
	public SwingBoard(Daedal game) {
	 
		this.vertex = ((DaedalBoard) game.getState()).getVertexes();
		this.edges = new ArrayList<Edge>();
		this.game = game;
		this.offset = 10;

		int nb = (int) Math.sqrt(game.getState().getSquares().size());
		setPreferredSize(new Dimension((nb + 1) * 50 + offset * 2, nb * 50 + offset
				* 2));

		for (Vertex v : this.vertex)
			edges.add(new Edge(v.getLocation(), this.offset, 50));

		edges.get(played = selected = 0).setSelected(true, Color.GREEN);

		setBackground(Color.DARK_GRAY);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see javax.swing.JComponent#paintComponent(java.awt.Graphics)
	 */
	@Override
	public void paintComponent(Graphics g) {
		super.paintComponent(g);

		Graphics2D g2 = (Graphics2D) g;
		Stroke ss = g2.getStroke();
		g2.setFont(font1);

		g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
				RenderingHints.VALUE_ANTIALIAS_ON);

		g2.setStroke(ss);
		g2.setColor(Color.LIGHT_GRAY);
		
		for (Vertex v : vertex) {
			int[] l = v.getLocation();
			g2.drawLine(l[0] * 50 + this.offset, l[1] * 50 + this.offset, l[2]
					* 50 + this.offset, l[3] * 50 + this.offset);
		}

		g2.setColor(Color.decode("0xEE4000"));
		g2.setStroke(Edge.STROKE);

		for (Vertex v : vertex) {

			int[] l = v.getLocation();
			if (v.valueBeforeAnalise())
				g2.drawLine(l[0] * 50 + this.offset, l[1] * 50 + this.offset,
						l[2] * 50 + this.offset, l[3] * 50 + this.offset);
		}
		
		g2.setStroke(ss);

		for (Box b : game.getState().getSquares()) {
			int x = 0, y = 0;

			for (Vertex v : b.getVertexes()) {
				x += (v.getLocation()[0] * 50 + this.offset);
				y += (v.getLocation()[1] * 50 + this.offset);
				x += (v.getLocation()[2] * 50 + this.offset);
				y += (v.getLocation()[3] * 50 + this.offset);
			}

			if (isClosed(b)) {
				if (b.getOwner().equals(DaedalTeam.BLACK)) {
					g.setColor(Color.BLACK);
				} else {
					g.setColor(Color.LIGHT_GRAY);
				}

				g.fillRoundRect(x / 8 - 20, y / 8 - 20, 40, 40, 15, 15);
				if (b.getOwner().equals(DaedalTeam.BLACK))
					g.setColor(Color.WHITE);
				else
					g.setColor(Color.BLACK);
			} else
				g.setColor(Color.BLACK);
			g.drawString(String.format("%02d", b.getValue()), x / 8
					- g.getFontMetrics().charWidth('0'), y / 8 + 6);
		}

		for (Edge e : edges) {
			e.paint(g);
		}
	}

	/**
	 * 
	 * @param b
	 * @return
	 */
	private boolean isClosed(Box b) {
		boolean result = true;
		
		for (Vertex v : b.getVertexes()){
			if (!v.valueBeforeAnalise()){
				result = false;
				break;
			}
		}

		return result;
	}



	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * java.awt.event.MouseMotionListener#mouseMoved(java.awt.event.MouseEvent)
	 */
	@Override
	public void mouseMoved(MouseEvent event) {
		for (int i = 0; i < edges.size(); i++) {
			Edge e = edges.get(i);
			if (e.isInside(event.getX(), event.getY())) {
				if (!e.equals(edges.get(selected))) {
					e.setSelected(true, Color.GREEN);
					edges.get(selected).setSelected(false, null);
					selected = i;
					repaint();
				}
				break;
			}
		}
	}
	
	/**
	 * 
	 * @param v
	 * @param c
	 */
	public void select(Vertex v, Color c){		
		for (int i = 0; i < vertex.size(); i++){
			if (vertex.get(i).equals(v)){
				edges.get(played).setSelected(false, null);
				edges.get(i).setSelected(true, c);
				played = i;
				repaint();
				break;
			}
		} 
	}

	/*
	 * (non-Javadoc)
	 * @see java.awt.event.MouseListener#mouseClicked(java.awt.event.MouseEvent)
	 */
	@Override
	public void mouseClicked(MouseEvent event) {
		if (event.getID() == MouseEvent.MOUSE_CLICKED
				&& !vertex.get(selected).isActive()) {
			waitMove(false);
			setMove(new Move<Vertex>(vertex.get(selected)));
		}
	}
	
	/**
	 * 
	 * @param b
	 */
	public void waitMove(boolean b) {
		if (b) {
			this.moved = null;
			addMouseListener(this);
			addMouseMotionListener(this);
			setCursor(Cursor.getDefaultCursor());
		} else {
			setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
			removeMouseListener(this);
			removeMouseMotionListener(this);
		}
	}
	
	/**
	 * 
	 * @return
	 */
	public synchronized Move<Vertex> getMove() {
		return this.moved;
	}
	
	/**
	 * 
	 * @return
	 */
	private synchronized void setMove(Move<Vertex> m) {
		this.moved=m;
	}
	
	/**
	 * 
	 * @return
	 */
	public Board<Box> getGameBoard(){
		return game.getState();
	}


	/**
	 * Campos privados
	 */
	private static final long serialVersionUID = 708912214167822250L;
	private static Font font1 = new Font("Arial", Font.BOLD, 20);
	private List<Vertex> vertex;
	private List<Edge> edges;
	private Daedal game;
	private int selected;
	private int played;
	private int offset;
	private Move<Vertex> moved = null;
}
